package simple.flow.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * jwt工具类
 *
 * @author lhd
 * @since 2025/4/8 14:14
 */

@Slf4j
public class JwtUtil {

    // token有效期为12小时
    public static final Long EXPIRATION_TIME = 12 * 60 * 60 * 1000L;

    // 设置秘钥明文 密钥过短会报 null empty 异常
    public static final String SECRET_KEY = "app_boot";

    /**
     * 生成token
     *
     * @param username 用户名
     * @return token
     */
    public static String createToken(String username, Map<String, String> claims) {
        if (username == null || username.isEmpty()) {
            throw new IllegalArgumentException("Jwt:createToken: username cannot be null or empty");
        }

        // 根据密码创建 HMAC256 算法实例
        Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);

        // 构建 JWT
        JWTCreator.Builder builder = JWT.create()
                // 设置 JWT ID
                .withJWTId(UUID.randomUUID().toString().replace("-", ""))
                // 设置过期时间
                .withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                // 设置用户名
                .withClaim("username", username);

        // 设置自定义声明
        if (!CollectionUtils.isEmpty(claims)) {
            claims.forEach(builder::withClaim);
        }

        // 使用算法签署 JWT
        return builder.sign(algorithm);
    }

    public static String createToken(String username) {
        return createToken(username, null);
    }

    /**
     * 验证token
     *
     * @param token 签名
     * @return 是否通过
     */
    public static boolean verifyToken(String token) {
        try {
            // 创建 HMAC256 算法实例
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            // 创建 JWT 验证器
            JWTVerifier verifier = JWT.require(algorithm).build();
            // 验证 JWT
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (JWTVerificationException exception) {
            // 验证失败，捕获异常
            return false;
        }
    }

    /**
     * 获取token
     *
     * @param request 请求
     * @return token
     */
    public static String getToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token == null || token.isEmpty()) {
            return null;
        }
        return token.replace("Bearer ", "");
    }

    /**
     * 获取token中的声明信息
     *
     * @param token    签名
     * @param claimKey 声明信息key
     * @return
     */
    public static String getClaim(String token, String claimKey) {
        try {
            // 创建 HMAC256 算法实例
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            // 创建 JWT 验证器
            JWTVerifier verifier = JWT.require(algorithm).build();
            // 验证并解码 JWT
            DecodedJWT jwt = verifier.verify(token);
            // 提取主题信息，即用户名
            return jwt.getClaim(claimKey).asString();
        } catch (JWTVerificationException exception) {
            // 验证失败，捕获异常
            return null;
        }
    }

    public static String getUsername(String token) {
        return getClaim(token, "username");
    }
}
